///
/// 日历组件，支持多种选择模式和自定义样式

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import '../../core/elegance_theme.dart';

/// 日历选择模式枚举
enum ECalendarMode {
  /// 单选模式
  single,
  
  /// 多选模式
  multiple,
  
  /// 范围选择模式
  range,
}

/// 日期选择器组件
class ECalendar extends StatefulWidget {
  /// 创建ECalendar组件
  const ECalendar({
    super.key,
    this.mode = ECalendarMode.single,
    this.startDate,
    this.endDate,
    this.defaultDate,
    this.minDate,
    this.maxDate,
    this.format = 'yyyy-MM-dd',
    this.showMoreDays = false,
    this.hideHeader = false,
    this.hideSubtitle = false,
    this.showWeekNumbers = false,
    this.monthNum = 1,
    this.marks,
    this.disabledDays,
    this.onDaySelected,
    this.onRangeSelected,
    this.onConfirm,
  });

  /// 选择模式
  final ECalendarMode mode;
  
  /// 开始日期，用于指定显示的第一个月份
  final DateTime? startDate;
  
  /// 结束日期，用于指定显示的最后一个月份
  final DateTime? endDate;
  
  /// 默认选中日期
  final DateTime? defaultDate;
  
  /// 可选的最小日期
  final DateTime? minDate;
  
  /// 可选的最大日期
  final DateTime? maxDate;
  
  /// 日期格式化模板
  final String format;
  
  /// 是否显示上个月和下个月的残余日期
  final bool showMoreDays;
  
  /// 是否隐藏头部
  final bool hideHeader;
  
  /// 是否隐藏副标题
  final bool hideSubtitle;
  
  /// 是否显示周数
  final bool showWeekNumbers;
  
  /// 显示的月份数量
  final int monthNum;
  
  /// 需要标记的日期列表
  final List<DateTime>? marks;
  
  /// 禁用的日期列表
  final List<DateTime>? disabledDays;
  
  /// 单选模式下选择日期的回调
  final Function(DateTime?)? onDaySelected;
  
  /// 范围选择模式下选择日期范围的回调
  final Function(DateTime?, DateTime?)? onRangeSelected;
  
  /// 确认选择的回调
  final Function(DateTime?)? onConfirm;

  @override
  ECalendarState createState() => ECalendarState();
}

class ECalendarState extends State<ECalendar> {
  /// 当前显示的年月
  late DateTime _currentDate;
  
  /// 选中的日期
  DateTime? _selectedDate;
  
  /// 范围选择的开始日期
  DateTime? _rangeStartDate;
  
  /// 范围选择的结束日期
  DateTime? _rangeEndDate;
  
  /// 多选的日期列表
  List<DateTime> _multipleSelectedDates = [];

  @override
  void initState() {
    super.initState();
    
    // 初始化当前日期
    _currentDate = widget.defaultDate ?? DateTime.now();
    
    // 初始化选中日期
    if (widget.defaultDate != null) {
      _selectedDate = widget.defaultDate;
    }
  }

  @override
  void didUpdateWidget(ECalendar oldWidget) {
    super.didUpdateWidget(oldWidget);
    
    // 如果默认日期发生变化，更新选中日期
    if (widget.defaultDate != oldWidget.defaultDate) {
      setState(() {
        _currentDate = widget.defaultDate ?? DateTime.now();
        _selectedDate = widget.defaultDate;
      });
    }
  }

  /// 处理日期点击
  void _onDayTap(DateTime date) {
    // 检查日期是否禁用
    if (_isDayDisabled(date)) {
      return;
    }

    setState(() {
      switch (widget.mode) {
        case ECalendarMode.single:
          _selectedDate = date;
          widget.onDaySelected?.call(date);
          widget.onConfirm?.call(date);
          break;
          
        case ECalendarMode.multiple:
          if (_multipleSelectedDates.contains(date)) {
            _multipleSelectedDates.remove(date);
          } else {
            _multipleSelectedDates.add(date);
          }
          break;
          
        case ECalendarMode.range:
          if (_rangeStartDate == null) {
            // 选择开始日期
            _rangeStartDate = date;
          } else if (_rangeEndDate == null && date.isAfter(_rangeStartDate!)) {
            // 选择结束日期（在开始日期之后）
            _rangeEndDate = date;
            widget.onRangeSelected?.call(_rangeStartDate, _rangeEndDate);
            widget.onConfirm?.call(_rangeStartDate);
          } else {
            // 重新选择开始日期
            _rangeStartDate = date;
            _rangeEndDate = null;
          }
          break;
      }
    });
  }

  /// 检查日期是否被禁用
  bool _isDayDisabled(DateTime date) {
    // 检查是否在禁用列表中
    if (widget.disabledDays != null && widget.disabledDays!.isNotEmpty) {
      for (var d in widget.disabledDays!) {
        if (_isSameDay(d, date)) {
          return true;
        }
      }
    }
    
    // 检查是否在最小日期之前
    if (widget.minDate != null && date.isBefore(widget.minDate!)) {
      return true;
    }
    
    // 检查是否在最大日期之后
    if (widget.maxDate != null && date.isAfter(widget.maxDate!)) {
      return true;
    }
    
    return false;
  }

  /// 检查日期是否有标记
  bool _isDayMarked(DateTime date) {
    if (widget.marks != null && widget.marks!.isNotEmpty) {
      for (var d in widget.marks!) {
        if (_isSameDay(d, date)) {
          return true;
        }
      }
    }
    return false;
  }

  /// 检查两个日期是否是同一天
  bool _isSameDay(DateTime date1, DateTime date2) {
    return date1.year == date2.year && 
           date1.month == date2.month && 
           date1.day == date2.day;
  }

  /// 检查日期是否在选中范围
  bool _isInSelectedRange(DateTime date) {
    if (widget.mode == ECalendarMode.range && 
        _rangeStartDate != null && 
        _rangeEndDate != null) {
      final startDate = _rangeStartDate!.subtract(const Duration(days: 1));
      final endDate = _rangeEndDate!.add(const Duration(days: 1));
      return date.isAfter(startDate) && date.isBefore(endDate);
    }
    return false;
  }

  /// 获取上个月
  void _previousMonth() {
    setState(() {
      _currentDate = DateTime(_currentDate.year, _currentDate.month - 1, 1);
    });
  }

  /// 获取下个月
  void _nextMonth() {
    setState(() {
      _currentDate = DateTime(_currentDate.year, _currentDate.month + 1, 1);
    });
  }

  /// 构建日历头部
  Widget _buildHeader(BuildContext context) {
    if (widget.hideHeader) {
      return Container();
    }

    final theme = EleganceTheme.of(context);
    final monthFormat = DateFormat('yyyy年MM月');

    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        IconButton(
          icon: Icon(Icons.chevron_left, color: theme.textPrimaryColor),
          onPressed: _previousMonth,
          splashRadius: 20,
        ),
        Text(
          monthFormat.format(_currentDate),
          style: TextStyle(
            fontSize: 16,
            fontWeight: FontWeight.bold,
            color: theme.textPrimaryColor,
          ),
        ),
        IconButton(
          icon: Icon(Icons.chevron_right, color: theme.textPrimaryColor),
          onPressed: _nextMonth,
          splashRadius: 20,
        ),
      ],
    );
  }

  /// 构建星期标题
  Widget _buildWeekDays(BuildContext context) {
    final theme = EleganceTheme.of(context);
    final weekDays = ['日', '一', '二', '三', '四', '五', '六'];

    return Row(
      children: [
        if (widget.showWeekNumbers) 
          Expanded(
            child: Center(
              child: Text(
                '周',
                style: TextStyle(
                  color: theme.textSecondaryColor,
                  fontSize: 14,
                ),
              ),
            ),
          ),
        ...weekDays.map((day) => Expanded(
          child: Center(
            child: Text(
              day,
              style: TextStyle(
                color: theme.textSecondaryColor,
                fontSize: 14,
              ),
            ),
          ),
        )),
      ],
    );
  }

  /// 构建日历格子
  Widget _buildDayCell(BuildContext context, DateTime date, bool isCurrentMonth) {
    final theme = EleganceTheme.of(context);
    final isToday = _isSameDay(date, DateTime.now());
    final isSelected = _selectedDate != null && _isSameDay(date, _selectedDate!);
    final isRangeStart = _rangeStartDate != null && _isSameDay(date, _rangeStartDate!);
    final isRangeEnd = _rangeEndDate != null && _isSameDay(date, _rangeEndDate!);
    final isInRange = _isInSelectedRange(date);
    final isMarked = _isDayMarked(date);
    final isDisabled = _isDayDisabled(date);
    final isMultiSelected = _multipleSelectedDates.any((d) => _isSameDay(d, date));

    Color textColor = theme.textPrimaryColor;
    Color bgColor = Colors.transparent;
    BoxDecoration? decoration;

    // 非当前月份的日期颜色更淡
    if (!isCurrentMonth && !widget.showMoreDays) {
      return Container();
    }
    
    if (!isCurrentMonth) {
      textColor = theme.textPlaceholderColor;
    }
    
    // 禁用状态
    if (isDisabled) {
      textColor = theme.textPlaceholderColor;
    }
    
    // 选中状态
    if (widget.mode == ECalendarMode.single && isSelected && !isDisabled) {
      bgColor = theme.primaryColor;
      textColor = Colors.white;
      decoration = BoxDecoration(
        color: bgColor,
        borderRadius: BorderRadius.circular(20),
      );
    }
    
    // 多选状态
    if (widget.mode == ECalendarMode.multiple && isMultiSelected && !isDisabled) {
      decoration = BoxDecoration(
        border: Border.all(color: theme.primaryColor),
        borderRadius: BorderRadius.circular(20),
      );
    }
    
    // 范围选择状态
    if (widget.mode == ECalendarMode.range) {
      if (isRangeStart && !isDisabled) {
        decoration = BoxDecoration(
          color: theme.primaryColor,
          borderRadius: const BorderRadius.only(
            topLeft: Radius.circular(20),
            bottomLeft: Radius.circular(20),
          ),
        );
        textColor = Colors.white;
      } else if (isRangeEnd && !isDisabled) {
        decoration = BoxDecoration(
          color: theme.primaryColor,
          borderRadius: const BorderRadius.only(
            topRight: Radius.circular(20),
            bottomRight: Radius.circular(20),
          ),
        );
        textColor = Colors.white;
      } else if (isInRange && !isDisabled) {
        decoration = BoxDecoration(
          color: theme.primaryLight,
        );
      }
    }
    
    // 今天的日期显示边框
    if (isToday && !isSelected && !isRangeStart && !isRangeEnd && !isDisabled) {
      decoration = BoxDecoration(
        border: Border.all(color: theme.primaryColor),
        borderRadius: BorderRadius.circular(20),
      );
    }

    return GestureDetector(
      onTap: isDisabled ? null : () => _onDayTap(date),
      child: Container(
        decoration: decoration,
        alignment: Alignment.center,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              '${date.day}',
              style: TextStyle(
                color: textColor,
                fontSize: 14,
              ),
            ),
            if (isMarked) 
              Container(
                width: 4,
                height: 4,
                margin: const EdgeInsets.only(top: 2),
                decoration: BoxDecoration(
                  color: theme.primaryColor,
                  shape: BoxShape.circle,
                ),
              ),
          ],
        ),
      ),
    );
  }

  /// 构建日历
  Widget _buildCalendar(BuildContext context) {
    final theme = EleganceTheme.of(context);
    final firstDay = DateTime(_currentDate.year, _currentDate.month, 1);
    final lastDay = DateTime(_currentDate.year, _currentDate.month + 1, 0);
    final daysInMonth = lastDay.day;
    final weekDayOfFirstDay = firstDay.weekday;
    
    // 计算需要显示的日期数量
    final daysToShow = daysInMonth + weekDayOfFirstDay;
    
    // 创建日期列表
    final List<DateTime> dates = [];
    
    // 添加上个月的日期
    for (int i = weekDayOfFirstDay - 1; i >= 0; i--) {
      dates.add(DateTime(_currentDate.year, _currentDate.month, -i));
    }
    
    // 添加当前月的日期
    for (int i = 1; i <= daysInMonth; i++) {
      dates.add(DateTime(_currentDate.year, _currentDate.month, i));
    }
    
    // 添加下个月的日期，使表格完整
    final remainingDays = (7 - (daysToShow % 7)) % 7;
    for (int i = 1; i <= remainingDays; i++) {
      dates.add(DateTime(_currentDate.year, _currentDate.month, daysInMonth + i));
    }
    
    // 构建日历网格
    final rows = <Widget>[];
    for (int i = 0; i < dates.length; i += 7) {
      final weekDates = dates.sublist(i, i + 7);
      rows.add(
        Row(
          children: [
            if (widget.showWeekNumbers) 
              Expanded(
                child: Container(
                  height: 40,
                  alignment: Alignment.center,
                  child: Text(
                    '${_getWeekNumber(weekDates.first)}',
                    style: TextStyle(
                      color: theme.textPlaceholderColor,
                      fontSize: 12,
                    ),
                  ),
                ),
              ),
            ...weekDates.map((date) => Expanded(
              child: Container(
                height: 40,
                child: _buildDayCell(context, date, date.month == _currentDate.month),
              ),
            )),
          ],
        ),
      );
    }
    
    return Column(
      children: rows,
    );
  }

  /// 获取日期所在的周数
  int _getWeekNumber(DateTime date) {
    // 简化实现，返回该月中的第几周
    final firstDay = DateTime(date.year, date.month, 1);
    final firstDayWeekday = firstDay.weekday;
    final dayOfMonth = date.day;
    
    return ((dayOfMonth + firstDayWeekday - 1) / 7).ceil();
  }

  @override
  Widget build(BuildContext context) {
    final theme = EleganceTheme.of(context);
    
    return Container(
      padding: const EdgeInsets.all(16),
      decoration: BoxDecoration(
        color: theme.surfaceColor,
        borderRadius: BorderRadius.circular(theme.borderRadius),
        border: Border.all(color: theme.borderColor),
      ),
      child: Column(
        children: [
          _buildHeader(context),
          SizedBox(height: widget.hideHeader ? 0 : 16),
          _buildWeekDays(context),
          SizedBox(height: 8),
          _buildCalendar(context),
        ],
      ),
    );
  }
}